package cn.wen.yaling.xo.service.impl;

import cn.wen.yaling.commons.constant.RedisConstants;
import cn.wen.yaling.commons.entity.ResourcesEntity;
import cn.wen.yaling.commons.enums.ResourceStatus;
import cn.wen.yaling.commons.enums.RoleStatus;
import cn.wen.yaling.commons.service.RedisService;
import cn.wen.yaling.commons.utils.RedisUtils;
import cn.wen.yaling.commons.utils.ResultEntity;
import cn.wen.yaling.commons.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.wen.yaling.commons.utils.PageUtils;
import cn.wen.yaling.commons.utils.Query;

import cn.wen.yaling.xo.dao.RoleDao;
import cn.wen.yaling.commons.entity.RoleEntity;
import cn.wen.yaling.xo.service.RoleService;
import org.springframework.transaction.annotation.Transactional;


@Service("roleService")
public class RoleServiceImpl extends ServiceImpl<RoleDao, RoleEntity> implements RoleService {

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<RoleEntity> page = this.page(
                new Query<RoleEntity>().getPage(params),
                new QueryWrapper<RoleEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public Set<String> getAllRoleNamesByUsername(String account) {
        return roleDao.selectAllRoleNamesByUsername(account);
    }

    @Override
    public ResultEntity getRoleList() {
        List<RoleEntity> roleList;
        // 1、先判断redis缓存中是否能命中缓存
        if (redisService.hasKey(RedisConstants.CACHE_ADMIN_ALL_ROLE_LIST)) {
            roleList = redisUtils.getListCache(RedisConstants.CACHE_ADMIN_ALL_ROLE_LIST, RoleEntity.class);
        } else {
            // 2、缓存不命中则到db中获取
            QueryWrapper<RoleEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.ne("role_status", RoleStatus.DELETED.getStatus());
            roleList = roleDao.selectList(queryWrapper);
            // 3、将db中的缓存获取到
            redisUtils.setListCache(RedisConstants.CACHE_ADMIN_ALL_ROLE_LIST, roleList);
        }
        return ResultEntity.ok().put("data", roleList);
    }

    @Override
    public ResultEntity addRole(RoleAddVO roleAddVO) {
        RoleEntity target = new RoleEntity();
        BeanUtils.copyProperties(roleAddVO, target);
        target.setCreateTime(new Date());
        target.setUpdateTime(new Date());
        target.setRoleStatus(0);
        boolean res = roleDao.insert(target) > 0;
        if (res) {
            redisService.del(RedisConstants.CACHE_ADMIN_ALL_ROLE_LIST);
            ResultEntity.ok();
        }
        return ResultEntity.error();
    }

    @Override
    public ResultEntity editRole(RoleUpdateVO roleVO) {
        RoleEntity target = new RoleEntity();
        BeanUtils.copyProperties(roleVO, target);
        target.setUpdateTime(new Date());
        boolean res = roleDao.updateById(target) > 0;
        if (res) {
            redisService.del(RedisConstants.CACHE_ADMIN_ALL_ROLE_LIST);
            ResultEntity.ok();
        }
        return ResultEntity.error();
    }

    @Override
    public ResultEntity deleteBatchRole(List<Integer> roleIds) {
        boolean res = roleDao.updateRoleStatusByIds(roleIds, 2);
        if (res) {
            redisService.del(RedisConstants.CACHE_ADMIN_ALL_ROLE_LIST);
            ResultEntity.ok();
        }
        return ResultEntity.error();
    }

    @Transactional
    @Override
    public ResultEntity updateRoleMenu(RoleMenuUpdateVO roleMenuVO) {
        // 1.先将数据库中的菜单和角色的连接信息删除
        roleDao.deleteRoleMenuRelation(roleMenuVO.getRoleId());
        // 2.然后将传入的数据添加
        boolean res = roleDao.insertRoleMenuRelation(roleMenuVO);
        if (res) return ResultEntity.ok();
        return ResultEntity.error();
    }

    @Transactional
    @Override
    public ResultEntity updateRolePermission(RolePermissionUpdateVO rolePermissionVO) {
        // 1.先将数据库中的权限和角色的连接信息删除
        roleDao.deleteRolePermissionRelation(rolePermissionVO.getRoleId());
        // 2.然后将传入的数据添加
        boolean res = roleDao.insertRolePermissionRelation(rolePermissionVO);
        if (res) return ResultEntity.ok();
        return ResultEntity.error();
    }

    @Override
    public ResultEntity getRoleMenuListById(Integer roleId) {
        List<Integer> permissionIds = roleDao.getRoleMenuListByRoleId(roleId);
        return ResultEntity.ok().put("data", permissionIds);
    }

    @Override
    public ResultEntity getRolePermissionListById(Integer roleId) {
        List<Integer> permissionIds = roleDao.getRolePermissionListById(roleId);
        return ResultEntity.ok().put("data", permissionIds);
    }

}